﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.Framework.Process;
using System.IO;
using PSE.ProcessManager.Entity;

namespace PSE.ProcessManager.Common.Process
{
    public class InteligenceManagerInstanceProcessManager : HierarchicalProcessManager<InteligenceManagerProcess,
                                                                                       ExecutorProcess,
                                                                                       IProcessService,
                                                                                       InteligenceManagerInstanceProcessManager>
    {
        private const string EXECUTOR_PATH_KEY = "ExecutorPath";

        protected override Uri GetServiceAddress()
        {
            return new Uri(string.Format("net.pipe://localhost/InteligenceManagerInstance/{0}", this.Name));
        }

        protected override IProcessService CreateServiceInstance()
        {
            return new ProcessService();
        }

        public bool IsChildStarted(int processId)
        {
            return this.IsChildStarted(this.Name + "_" + processId.ToString());
        }

        public ExecutorProcess GetChild(int processId)
        {
            if (this.IsChildStarted(processId))
            {
                return this.Children[this.Name + "_" + processId.ToString()];
            }
            else
            {
                return null;
            }
        }

        public ExecutorProcess StartChild(ProcessEntity processConfiguration,
                                          string executorConfigPath,
                                          string domain,
                                          string userName,
                                          string password)
        {
            string executorFileName = System.Configuration.ConfigurationManager.AppSettings[EXECUTOR_PATH_KEY];

            if (String.IsNullOrEmpty(executorFileName))
                throw new Exception(string.Format("The '{0}' configuration must be informed.", EXECUTOR_PATH_KEY));

            bool autoRecovery = false;

            if (processConfiguration.InitializationType == PSE.ProcessManager.Entity.Enums.StartUpType.Automatic &&
                processConfiguration.FailureRecovery == PSE.ProcessManager.Entity.Enums.FailureActions.RestartProcess)
                autoRecovery = true;

            ExecutorProcess process = this.StartChild(new ChildProcessStartInfo()
            {
                Name = this.Name + "_" + processConfiguration.Id,
                FileName = executorFileName,
                Arguments = '"' + executorConfigPath.Replace(@"\", @"\\") + '"' + " " +
                            '"' + processConfiguration.Assembly.Replace(@"\", @"\\") + '"' + " " +
                            '"' + processConfiguration.Class + '"',
                Domain = domain,
                UserName = userName,
                Password = password,
                CheckParentIsAlive = true,
                CheckChildIsAlive = autoRecovery
            });

            return process;
        }

        public void CloseChild(int processId)
        {
            this.CloseChild(this.Name + "_" + processId.ToString());
        }
    }
}
